<?php
// 应用公共文件

use think\facade\Cache;
use think\facade\Db;

if (!function_exists('__url')) {

    /**
     * 构建URL地址
     * @param string $url
     * @param array $vars
     * @param bool $suffix
     * @param bool $domain
     * @return string
     */
    function __url(string $url = '', array $vars = [], bool $suffix = true, bool $domain = false): string
    {
        return url($url, $vars, $suffix, $domain)->build();
    }
}

if (!function_exists('password')) {

    /**
     * 密码加密算法
     * @param $value
     * @return string
     */
    function password($value): string
    {
        $value = sha1('blog_') . md5($value) . md5('_encrypt') . sha1($value);
        return sha1($value);
    }
}

if (!function_exists('isDebug')) {
    /**
     * 是否为调试模式
     * @return bool
     */
    function isDebug(): bool
    {
        return app()->isDebug();
    }
}

if (!function_exists('sysConfig')) {

    /**
     * 获取系统配置信息
     * @param $group
     * @param $name
     * @return mixed
     */
    function sysConfig($group, $name = null): mixed
    {
        $appName = app()->http->getName();
        $appName = $appName == "admin" || $appName == "mini" ? "group" : "company";
        $table = $appName . '_config';
        $where = ['group' => $group];
        $value = empty($name) ? Cache::get("config_{$appName}_{$group}") :
            Cache::get("config_{$appName}_{$group}_{$name}");
        if (empty($value)) {
            if (!empty($name)) {
                $where['name'] = $name;
                $value = Db::name($table)->where($where)->value('value');
                Cache::tag('config')->set("config_{$appName}_{$group}_{$name}", $value, 3600);
            } else {
                $value = Db::name($table)->where($where)->column('value', 'name');
                Cache::tag('config')->set("config_{$appName}_{$group}", $value, 3600);
            }
        }
        return $value;
    }
}

if (!function_exists('geocodeConfig')) {

    /**
     * 获取位置配置
     */
    function geocodeConfig($name = null): mixed
    {
        $where = ['group' => 'local'];
//        $value = Cache::get('config_local');
        $value = '';
        if (empty($value)) {
            if (!empty($name)) {
                $where['name'] = $name;
                $value = Db::name('group_config')->where($where)->value('value');
                Cache::tag('ge_config')->set("config_local", $value, 3600);
            } else {
                $value = Db::name('group_config')->where($where)->column('value', 'name');
                Cache::tag('ge_config')->set("config_local", $value, 3600);
            }
        }
        return $value;
    }
}

if (!function_exists('generateOrderNo')) {

    /**
     * 生成单号
     * @param string $prefix
     * @param int $number
     * @return string
     */
    function generateOrderNo(string $prefix = ''): string
    {
        return $prefix . date('YmdHis') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
    }
}

/**
 * 获取两个时间差(用于商品过期预警)
 * @param $created_time
 * @param int $start_time
 * @return false|int
 * @throws Exception
 */
function difTime($created_time, int $start_time = 0): bool|int
{
    if (0 == $created_time) {
        return 0;
    }
    $createdTime = new DateTime(date("Ymd His", $created_time));
    // 获取当前时间
    if (0 == $start_time)   $now = new DateTime();
    if (0 != $start_time)   $now = new DateTime(date("Ymd His", $start_time));

    $diff = $now->diff($createdTime);

    return abs($diff->days);
}

/**
 * 驼峰转下划线
 */
if (!function_exists('lineToHump')) {
    function humpToLine($str): array|string|null
    {
        $str = preg_replace_callback('/([A-Z]{1})/', function ($matches) {
            return '_' . strtolower($matches[0]);
        }, $str);
        return $str;
    }
}


if (!function_exists('arrayReduce')) {

    /**
     * array_reduce
     * @param $data
     * @param $field1
     * @param $field2
     * 当第二个字段参数存在，执行元素字段相乘后累加
     */
    function arrayReduce($data, $field1, $field2 = null): int
    {
        return array_reduce($data, static function ($carry, $item) use ($field1, $field2) {
            if ($field1 && $field2) {
                $newNumber = $item[$field1] * $item[$field2];
                $value = $carry + $newNumber;
            } else {
                $value = $carry + $item[$field1];
            }
            return $value;
        }, 0);
    }
}


if (!function_exists('array_format_key')) {

    /**
     * 二位数组重新组合数据
     * @param $array
     * @param $key
     * @return array
     */
    function array_format_key($array, $key): array
    {
        $newArray = [];
        foreach ($array as $vo) {
            $newArray[$vo[$key]] = $vo;
        }
        return $newArray;
    }

}

if (!function_exists('distance')) {

    /**
     * 计算距离
     * @param $lng
     * @param $lat
     * @return string
     */
    function distance($lng, $lat): string
    {
        return "(6378.138 * 2 * ASIN(SQRT(
        POWER(SIN(({$lat} - `lat`) * PI() / 180 / 2), 2) +
        COS({$lat} * PI() / 180) * COS(`lat` * PI() / 180) *
        POWER(SIN(({$lng} - `lon`) * PI() / 180 / 2), 2))) * 1000) AS distance";
    }

}

if (!function_exists('isValidLatLng')) {

    /**
     * 判断是否是合理的经纬度
     * @param $lat
     * @param $lon
     * @return bool
     */
    function isValidLatLng($lat, $lon): bool
    {
        // 将输入的字符串转换为浮点数
        $lat = floatval($lat);
        $lon = floatval($lon);

        // 检查纬度是否在有效范围内
        if ($lat < -90 || $lat > 90) {
            return false;
        }

        // 检查经度是否在有效范围内
        if ($lon < -180 || $lon > 180) {
            return false;
        }

        // 如果所有检查都通过，则认为是有效的经纬度
        return true;
    }

}

if (!function_exists('getMoneyLength')) {

    /**
     * 判断金额长度
     * @param $amount
     * @return string
     */
    function getMoneyLength($amount): string
    {
        // 将金额转换为字符串
        $amountStr = (string)$amount;

        // 检查是否有小数点
        $dotPos = strpos($amountStr, '.');

        // 如果有小数点，计算小数点前后的长度
        if ($dotPos !== false) {
            // 小数点前的数字长度
            $intLength = $dotPos;
            // 小数点后的数字长度
//            $decimalLength = strlen($amountStr) - $dotPos - 1;
            // 总长度是整数部分和小数部分长度之和
            return $intLength;
        } else {
            // 如果没有小数点，直接返回长度
            return strlen($amountStr);
        }
    }

}

if (!function_exists('arrayGroupBy')) {

    /**
     * 数组分组
     * @param array $array
     * @param callable $key_func
     * @return array
     */
    function arrayGroupBy(array $array, callable $key_func): array
    {
        $grouped = [];
        foreach ($array as $value) {
            $group_key = call_user_func($key_func, $value);
            $grouped[$group_key][] = $value;
        }
        return $grouped;
    }

}

